unit ICQ_RemoteCP_Users;

interface

uses
 StringsSettings;

const
 cUsersMax = 1000;

 //user types
 utSupervisor = 0;
 utAdmin = 1;
 utUser = 2;
 utNoBody = 3;
 utNotFound = utNoBody+1;
 //settings
 ssUsers = 'Users';
 //tokens
 tknID = 'id';
 tknType = 'type';
 tknDumb = 'dumb';

 MaxDumbTries = 5;

function IsUIN(UIN: String): Boolean;
//
function NewUserStr(const AID: String; AType: Integer = utUser): String;
procedure AddNewUser(const Settings: TStringsSettings; const AID: String; AType: Integer = utUser);
function DelUser(const Settings: TStringsSettings; AID: String): Boolean;
function UserDumbCount(Data: String): Integer; overload;
function UserDumbInc(Data: String): String; overload;
function UserID(Data: String): String; overload;
function UserIndexByID(const Settings: TStringsSettings; AID: String): Integer;
function UserType(Data: String): Integer; overload;
function UserType(const Settings: TStringsSettings; AID: String): Integer; overload;
function UserDumbCount(const Settings: TStringsSettings; AID: String): Integer; overload;
procedure UserDumbInc(const Settings: TStringsSettings; AID: String); overload;
function ChangeUserTypeStr(const Data: String; NewType: Integer = utUser): String;
procedure ChangeUserType(const Settings: TStringsSettings; const AID: String; NewType: Integer = utUser);
function UserDumbClear(Data: String): String; overload;
procedure UserDumbClear(const Settings: TStringsSettings; AID: String); overload;
procedure NoBodyClear(const Settings: TStringsSettings);
function GetSupervisorID(const Settings: TStringsSettings): String;
//
procedure OnlyOneSupervisor(Index: Integer = -1; Settings: TStringsSettings = nil);

implementation

uses
 SysUtils,
 ICQ_RemoteCP_Settings,
 ICQ_RemoteCP_Store,
 Tokens;

function IsUIN(UIN: String): Boolean;
begin
 Result:=StrToIntDef(UIN, 0)>0;
end;

function UserType(Data: String): Integer;
 var
  s: String;
begin
 s:=ExtractToken(tknType, Data);
 if s='' then
   Result:=utNotFound
 else
   Result:=StrToIntDef(s, utNoBody);
end;

function UserType(const Settings: TStringsSettings; AID: String): Integer;
begin
 if Assigned(Settings) then
   Result:=UserType(Settings.Group[ssUsers, UserIndexByID(Settings, AID)])
 else
   Result:=utNotFound;
end;

function ChangeUserTypeStr(const Data: String; NewType: Integer = utUser): String;
begin
 Result:=CopyToken(tknID, Data);
 if NewType in [utSupervisor..utNoBody] then
   Result:=Result+EncodeToken(tknType, IntToStr(NewType))
 else
   Result:=Result+CopyToken(tknType, Data);
 Result:=Result+CopyToken(tknDumb, Data);
end;

procedure ChangeUserType(const Settings: TStringsSettings; const AID: String; NewType: Integer = utUser);
 var
  i: Integer;
begin
 if Assigned(Settings) then
  begin
   i:=UserIndexByID(Settings, AID);
   if i>=0 then
     Settings.Group[ssUsers, i]:=ChangeUserTypeStr(Settings.Group[ssUsers, i], NewType);
  end
end;

function NewUserStr(const AID: String; AType: Integer = utUser): String;
begin
 if AType in [utSupervisor..utNoBody] then
   Result:=EncodeToken(tknID, AID)+EncodeToken(tknType, IntToStr(AType))
 else
   Result:='';
end;

procedure AddNewUser(const Settings: TStringsSettings; const AID: String; AType: Integer = utUser);
 var
  i: Integer;
begin
 if Assigned(Settings) then
  begin
   i:=UserIndexByID(Settings, AID);
   if i<0 then
     Settings.AddValueToGroup(ssUsers, NewUserStr(AID, AType))
   else
     ChangeUserType(Settings, AID, AType);
  end;
end;

function DelUser(const Settings: TStringsSettings; AID: String): Boolean;
 var
  i: Integer;
begin
 Result:=false;
 if Assigned(Settings) then
  begin
   i:=UserIndexByID(Settings, AID);
   if i>=0 then
    begin
     Settings.DeleteValueFromGroup(ssUsers, i);
     Result:=true;
    end;
  end;
end;

function UserID(Data: String): String;
begin
 Result:=ExtractToken(tknID, Data);
end;

function UserDumbCount(Data: String): Integer;
begin
 Result:=StrToIntDef(ExtractToken(tknDumb, Data), 0);
end;

function UserDumbInc(Data: String): String;
 var
  i: Integer;
begin
 Result:=CopyToken(tknID, Data)+CopyToken(tknType, Data);
 i:=UserDumbCount(Data);
 if i<MaxDumbTries then
  begin
   Inc(i);
   Result:=Result+EncodeToken(tknDumb, IntToStr(i));
  end
 else
   Result:=Result+CopyToken(tknDumb, Data);
end;

procedure UserDumbInc(const Settings: TStringsSettings; AID: String);
 var
  i: Integer;
begin
 if Assigned(Settings) then
  begin
   i:=UserIndexByID(Settings, AID);
   if i>=0 then
     Settings.Group[ssUsers, i]:=UserDumbInc(Settings.Group[ssUsers, i]);
  end;
end;

function UserIndexByID(const Settings: TStringsSettings; AID: String): Integer;
begin
 if Assigned(Settings) then
   Result:=Settings.GroupTokenIndex(ssUsers, tknID, AID)
 else
   Result:=-1;
end;

function UserDumbCount(const Settings: TStringsSettings; AID: String): Integer; overload;
begin
 if Assigned(Settings) then
   Result:=UserDumbCount(Settings.Group[ssUsers, UserIndexByID(Settings, AID)])
 else
   Result:=0;
end;

function UserDumbClear(Data: String): String;
begin
 Result:=CopyToken(tknID, Data)+CopyToken(tknType, Data);
end;

procedure UserDumbClear(const Settings: TStringsSettings; AID: String);
 var
  i: Integer;
begin
 if Assigned(Settings) then
  begin
   i:=UserIndexByID(Settings, AID);
   if i>=0 then
     Settings.Group[ssUsers, i]:=UserDumbClear(Settings.Group[ssUsers, i]);
  end
end;

procedure NoBodyClear(const Settings: TStringsSettings);
 var
  i, ut: Integer;
begin
 if Assigned(Settings) then
  begin
   i:=0;
   while i<Settings[ssUsers] do
    begin
     ut:=UserType(Settings.Group[ssUsers, i]);
     if ut=utNobody then
       Settings.DeleteValueFromGroup(ssUsers, i)
     else
       Inc(i);
    end;
  end;
end;

function GetSupervisorID(const Settings: TStringsSettings): String;
 var
  i: Integer;
begin
 if Assigned(Settings) then
  begin
   i:=Settings.GroupTokenIndex(ssUsers, tknType, IntToStr(utSupervisor));
   if i<0 then
     Result:=''
   else
     Result:=UserID(Settings.Group[ssUsers, i]);
  end
 else
   Result:='';
end;

procedure OnlyOneSupervisor(Index: Integer = -1; Settings: TStringsSettings = nil);
 var
  i: Integer;
begin
 if not Assigned(Settings) then
   Settings:=Sets;
 //
 if Assigned(Settings) then
  begin
   if (Index<0) or (Index>=Settings[ssUsers]) then
     i:=Settings.GroupTokenIndex(ssUsers, tknType, IntToStr(utSupervisor))
   else
     i:=Index;
   if i>=0 then //there can be no supervisor yet so we need to check
     Settings.TokenValueCountInGroupValue(ssUsers, tknType, i, IntToStr(utSupervisor), IntToStr(utAdmin), Settings[cSupervisors]);
  end;
end;

end.
